package midend.IR_Instruction;

import midend.IR_Type.IR_Type;
import midend.IR_Value.IR_BaseBlock;
import midend.IR_Value.IR_FuncBlock;
import midend.IR_Value.IR_Local_Value;
import midend.IR_Value.IR_Value;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static midend.IR_Type.IR_Const.*;

public class Calc_Instruction extends Instruction{
    String op_Type;
    boolean is64 = false;
    public Calc_Instruction(List<IR_Value> op, IR_BaseBlock bb, String op_Type) {
        super(op, bb);
        this.op_Type = op_Type;
        addValue(get_op_index(1));
        addValue(get_op_index(2));
    }
    public void updateop(int index, IR_Value newValue) {
        if(index >= 0 && index <= 1){
            set_Op(index + 1, newValue);
        }
    }
    public String get_op_Type() {
        return op_Type;
    }

    public boolean getIs64(){
        return is64;
    }
    //todo
    public void setIs64() {
        this.is64 = true;
    }

    @Override
    public String toString() {
        IR_Value res = get_op().get(0);
        IR_Value value1 = get_op().get(1);
        IR_Value value2 = get_op().get(2);
        switch(op_Type){
            case XOR:
                return res.get_ValueName() +
                        " = " + XOR + " " +
                        value2.get_Type().get_TypeName() + " " +
                        value1.get_ValueName() + ", true";
            default:
                //ADD SUB MUL FADD FSUB  FMUL SDIV FDIV SREM SHL Ashr lshr
                return res.get_ValueName() +
                        " = " + op_Type + " " +
                        res.get_Type().get_TypeName() + " " +
                        value1.get_ValueName() + ", " +
                        value2.get_ValueName();
        }

    }


    @Override
    public Calc_Instruction clone(IR_BaseBlock block) {
        String copy_name = ((IR_Local_Value) get_op().get(0)).get_Local_Identity();
        IR_Type copy_type = get_op().get(0).get_Type();
        IR_Value res = new IR_Local_Value(copy_name, copy_type);
        ArrayList<IR_Value> copy_ops = new ArrayList<>();
        copy_ops.add(res);
        for (int i = 1 ; i< get_op().size() ; i++) {
            IR_Value copy_op  = get_op().get(i);
            if(IR_FuncBlock.cloneMap_Value.containsKey(copy_op)) {
                copy_op = IR_FuncBlock.cloneMap_Value.get(copy_op);
            }
            copy_ops.add(copy_op);
        }
        Calc_Instruction aluInstr = new Calc_Instruction(copy_ops, block, this.get_op_Type());
        aluInstr.is64 = this.is64;
        return aluInstr;
    }
}
